package orm

import (
	"animal/octopus/common"
	"animal/octopus/model"
	"time"

	log "github.com/sirupsen/logrus"
	"gorm.io/gorm"
)

// ------------------------------------------------------------------------------
//
// ------------------------------------------------------------------------------
func GetEventList(db *gorm.DB, param common.GetEventListParam) ([]model.Event, uint, error) {
	ldb := common.DB(db)

	if param.PageSize <= 0 {
		log.WithField("page_size", param.PageSize).Error("invalid page size")
		return nil, 0, common.NewErrCode(common.ErrInvalidParam)
	}

	if param.PageIndex <= 0 {
		log.WithField("page_index", param.PageSize).Error("invalid page index")
		return nil, 0, common.NewErrCode(common.ErrInvalidParam)
	}

	if param.ModuleName != "" {
		ldb = ldb.Where("events.module_name = ?", param.ModuleName)
	}

	if param.EventType != "" {
		ldb = ldb.Where("events.event_type = ?", param.EventType)
	}

	if param.StartTime != "" {
		t, err := time.Parse("2006-01-02 15:04:05", param.StartTime)
		if err != nil {
			log.WithFields(log.Fields{
				"startTime": param.StartTime,
				"error":     err,
			}).Error("parse start time failed")
			return nil, 0, common.NewErrCode(common.ErrInvalidParam)
		}
		ldb.Where("created_at > ?", t)
	}

	if param.EndTime != "" {
		t, err := time.Parse("2006-01-02 15:04:05", param.EndTime)
		if err != nil {
			log.WithFields(log.Fields{
				"endTime": param.EndTime,
				"error":   err,
			}).Error("parse end time failed")
			return nil, 0, common.NewErrCode(common.ErrInvalidParam)
		}
		ldb.Where("created_at < ?", t)
	}

	var totalCount int64 = 0
	ldb.Find(&[]model.Event{}).Count(&totalCount)

	var events []model.Event
	if err := ldb.Offset(int(param.PageSize) * int(param.PageIndex-1)).
		Limit(int(param.PageSize)).Find(&events).Error; err != nil {
		log.WithField("error", err).Error("find events from database failed")
		return nil, 0, err
	}

	log.WithField("size", len(events)).Info("find events success")

	return events, uint(totalCount), nil
}

// ------------------------------------------------------------------------------
//
// ------------------------------------------------------------------------------
func CreateEvent(db *gorm.DB, param common.CreateEventParam) (uint, error) {
	if result := common.DB(db).Create(&model.Event{
		RootModuleID: param.RootModuleID,
		ModuleID:     param.ModuleID,
		ModuleName:   param.ModuleName,
		Type:         param.EventType,
		Attribute:    param.Attribute,
	}); result.Error != nil {
		log.WithFields(log.Fields{
			"param": common.MustMarshal(param),
			"error": result.Error,
		}).Error("create event failed")
		return 0, common.NewErrCode(common.ErrDatabaseError)
	}

	return 0, nil
}

// ------------------------------------------------------------------------------
//
// ------------------------------------------------------------------------------
func DeleteEvent(db *gorm.DB, param common.DeleteEventParam) error {
	if err := common.DB(db).Unscoped().Delete(&model.Event{}, param.EventID).Error; err != nil {
		log.WithFields(log.Fields{
			"id":    param.EventID,
			"error": err,
		}).Error("delete event failed")
		return common.NewErrCode(common.ErrDatabaseError)
	}
	return nil
}
